package com.kaizeli.website.controller;

import com.kaizeli.website.response.Result;
import com.kaizeli.website.service.WarningService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 预警管理控制器
 */
@Tag(name = "预警相关接口", description = "预警查询和处理相关接口")
@RestController
@RequestMapping("/api/warning")
public class WarningController {

    @Autowired
    private WarningService warningService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Operation(summary = "手动触发预警检查", description = "立即执行一次完整的预警检查（测试用）")
    @PostMapping("/check")
    public Result<String> triggerWarningCheck() {
        warningService.executeAllWarningChecks();
        return Result.success("预警检查已完成");
    }

    @Operation(summary = "获取预警列表", description = "查询预警记录，支持按类型、级别、状态筛选")
    @GetMapping("/list")
    public Result<List<Map<String, Object>>> getWarningList(
            @Parameter(description = "预警类型(acceptance/payment/personnel/contract)") 
            @RequestParam(required = false) String warningType,
            @Parameter(description = "预警级别(info/warning/critical)") 
            @RequestParam(required = false) String warningLevel,
            @Parameter(description = "预警状态(active/handled/ignored/auto_closed)") 
            @RequestParam(required = false) String status,
            @Parameter(description = "每页数量") 
            @RequestParam(defaultValue = "20") Integer limit) {
        
        // 输入验证：白名单验证
        if (warningType != null && !isValidWarningType(warningType)) {
            return Result.error(400, "无效的预警类型");
        }
        if (warningLevel != null && !isValidWarningLevel(warningLevel)) {
            return Result.error(400, "无效的预警级别");
        }
        if (status != null && !isValidWarningStatus(status)) {
            return Result.error(400, "无效的预警状态");
        }
        if (limit < 1 || limit > 100) {
            return Result.error(400, "每页数量必须在1-100之间");
        }
        
        StringBuilder sql = new StringBuilder(
            "SELECT id, warning_no, rule_code, warning_type, warning_level, " +
            "related_id, related_table, warning_title, warning_content, " +
            "warning_time, status, handled_by, handled_time " +
            "FROM warning_records WHERE 1=1 "
        );
        
        List<Object> params = new java.util.ArrayList<>();
        
        if (warningType != null && !warningType.isEmpty()) {
            sql.append(" AND warning_type = ?");
            params.add(warningType);
        }
        
        if (warningLevel != null && !warningLevel.isEmpty()) {
            sql.append(" AND warning_level = ?");
            params.add(warningLevel);
        }
        
        if (status != null && !status.isEmpty()) {
            sql.append(" AND status = ?");
            params.add(status);
        } else {
            // 默认只显示活动的预警
            sql.append(" AND status = ?");
            params.add("active");
        }
        
        sql.append(" ORDER BY warning_time DESC LIMIT ?");
        params.add(limit);
        
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql.toString(), params.toArray());
        return Result.success(list);
    }
    
    /**
     * 验证预警类型是否合法
     */
    private boolean isValidWarningType(String warningType) {
        java.util.Set<String> validTypes = java.util.Set.of(
            "acceptance", "payment", "personnel", "contract"
        );
        return validTypes.contains(warningType);
    }
    
    /**
     * 验证预警级别是否合法
     */
    private boolean isValidWarningLevel(String warningLevel) {
        java.util.Set<String> validLevels = java.util.Set.of(
            "info", "warning", "critical"
        );
        return validLevels.contains(warningLevel);
    }
    
    /**
     * 验证预警状态是否合法
     */
    private boolean isValidWarningStatus(String status) {
        java.util.Set<String> validStatuses = java.util.Set.of(
            "active", "handled", "ignored", "auto_closed"
        );
        return validStatuses.contains(status);
    }

    @Operation(summary = "获取预警统计", description = "统计各类型、各级别的预警数量")
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getWarningStatistics() {
        String sql = "SELECT " +
                    "COUNT(*) as total, " +
                    "SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_count, " +
                    "SUM(CASE WHEN warning_level = 'critical' AND status = 'active' THEN 1 ELSE 0 END) as critical_count, " +
                    "SUM(CASE WHEN warning_level = 'warning' AND status = 'active' THEN 1 ELSE 0 END) as warning_count, " +
                    "SUM(CASE WHEN warning_level = 'info' AND status = 'active' THEN 1 ELSE 0 END) as info_count, " +
                    "SUM(CASE WHEN warning_type = 'acceptance' AND status = 'active' THEN 1 ELSE 0 END) as acceptance_count, " +
                    "SUM(CASE WHEN warning_type = 'payment' AND status = 'active' THEN 1 ELSE 0 END) as payment_count, " +
                    "SUM(CASE WHEN warning_type = 'personnel' AND status = 'active' THEN 1 ELSE 0 END) as personnel_count, " +
                    "SUM(CASE WHEN warning_type = 'contract' AND status = 'active' THEN 1 ELSE 0 END) as contract_count " +
                    "FROM warning_records";
        
        Map<String, Object> stats = jdbcTemplate.queryForMap(sql);
        return Result.success(stats);
    }

    @Operation(summary = "获取预警详情", description = "根据ID查询预警详细信息")
    @GetMapping("/{id}")
    public Result<Map<String, Object>> getWarningDetail(
            @Parameter(description = "预警ID") @PathVariable Long id) {
        
        String sql = "SELECT * FROM warning_records WHERE id = ?";
        try {
            Map<String, Object> warning = jdbcTemplate.queryForMap(sql, id);
            return Result.success(warning);
        } catch (Exception e) {
            return Result.error(404, "预警记录不存在");
        }
    }

    @Operation(summary = "处理预警", description = "标记预警为已处理")
    @PostMapping("/{id}/handle")
    public Result<Void> handleWarning(
            @Parameter(description = "预警ID") @PathVariable Long id,
            @Parameter(description = "处理备注") @RequestParam(required = false) String remark) {
        
        String sql = "UPDATE warning_records " +
                    "SET status = 'handled', handled_time = NOW(), handle_remark = ? " +
                    "WHERE id = ? AND status = 'active'";
        
        int count = jdbcTemplate.update(sql, remark, id);
        if (count > 0) {
            return Result.success(null);
        } else {
            return Result.error(400, "预警不存在或已处理");
        }
    }

    @Operation(summary = "忽略预警", description = "标记预警为已忽略")
    @PostMapping("/{id}/ignore")
    public Result<Void> ignoreWarning(
            @Parameter(description = "预警ID") @PathVariable Long id,
            @Parameter(description = "忽略原因") @RequestParam(required = false) String remark) {
        
        String sql = "UPDATE warning_records " +
                    "SET status = 'ignored', handled_time = NOW(), handle_remark = ? " +
                    "WHERE id = ? AND status = 'active'";
        
        int count = jdbcTemplate.update(sql, remark, id);
        if (count > 0) {
            return Result.success(null);
        } else {
            return Result.error(400, "预警不存在或已处理");
        }
    }

    @Operation(summary = "批量处理预警", description = "批量标记预警为已处理")
    @PostMapping("/batch/handle")
    public Result<Integer> batchHandleWarnings(
            @Parameter(description = "预警ID列表") @RequestBody List<Long> ids,
            @Parameter(description = "处理备注") @RequestParam(required = false) String remark) {
        
        if (ids == null || ids.isEmpty()) {
            return Result.error(400, "预警ID列表不能为空");
        }
        
        // 防止SQL注入：构建占位符
        String placeholders = String.join(",", java.util.Collections.nCopies(ids.size(), "?"));
        String sql = "UPDATE warning_records " +
                    "SET status = 'handled', handled_time = NOW(), handle_remark = ? " +
                    "WHERE id IN (" + placeholders + ") " +
                    "AND status = 'active'";
        
        // 构建参数数组：第一个参数是remark，后面是所有的ids
        List<Object> params = new java.util.ArrayList<>();
        params.add(remark);
        params.addAll(ids);
        
        int count = jdbcTemplate.update(sql, params.toArray());
        return Result.success(count);
    }

    @Operation(summary = "获取预警规则列表", description = "查询所有预警规则配置")
    @GetMapping("/rules")
    public Result<List<Map<String, Object>>> getWarningRules() {
        String sql = "SELECT id, rule_code, rule_name, rule_type, warning_level, " +
                    "warning_days, enabled, description " +
                    "FROM warning_rules " +
                    "ORDER BY rule_type, id";
        
        List<Map<String, Object>> rules = jdbcTemplate.queryForList(sql);
        return Result.success(rules);
    }

    @Operation(summary = "启用/禁用预警规则", description = "切换预警规则的启用状态")
    @PostMapping("/rules/{id}/toggle")
    public Result<Void> toggleWarningRule(
            @Parameter(description = "规则ID") @PathVariable Long id) {
        
        String sql = "UPDATE warning_rules SET enabled = 1 - enabled WHERE id = ?";
        int count = jdbcTemplate.update(sql, id);
        
        if (count > 0) {
            return Result.success(null);
        } else {
            return Result.error(404, "规则不存在");
        }
    }

    @Operation(summary = "清理历史预警", description = "删除30天前的已处理预警记录")
    @DeleteMapping("/cleanup")
    public Result<Integer> cleanupOldWarnings() {
        String sql = "DELETE FROM warning_records " +
                    "WHERE status IN ('handled', 'ignored', 'auto_closed') " +
                    "AND handled_time < DATE_SUB(NOW(), INTERVAL 30 DAY)";
        
        int count = jdbcTemplate.update(sql);
        return Result.success(count);
    }

    @Operation(summary = "清除所有预警", description = "清除数据库和WebSocket中的所有预警信息，只有再次触发预警检查才会生成新预警")
    @PostMapping("/clear")
    public Result<String> clearAllWarnings() {
        try {
            warningService.clearAllWarnings();
            return Result.success("所有预警已清除，下次触发预警检查时将重新生成预警");
        } catch (Exception e) {
            return Result.error(500, "清除预警失败: " + e.getMessage());
        }
    }
}
